<template>
	<a-input-group compact class="search-input-group">
		<template v-if="matchTypes && matchTypes.length">
			<a-select v-model:value="params.matchType" :options="matchTypes" style="width: auto; min-width: 110px" />
		</template>
		<a-select
			v-model:value="params.like"
			:search-value="params.like"
			v-bind="option"
			class="search-input-wrapper"
			@click.stop
			@keydown.enter="search()">
			<template #suffixIcon>
				<search-outlined style="color: #000; opacity: 0.7; font-size: 14px" @click="search(true)" />
			</template>
			<template #dropdownRender="{menuNode}">
				<template v-if="options && options.length">
					<a-form :id="id" :model="params" layout="vertical" class="search-form-wrapper" @click.stop @keydown.enter="search()">
						<a-form-item v-for="(o, i) in options" :key="i" :label="o.label" class="search-item-wrapper">
							<template v-if="o.component === 'deptEmpSelect'">
								<dept-emp-select
									v-model:dept-id="params[o.field[0]]"
									v-model:emp-id="params[o.field[1]]"
									:disabled="!!(originParams[o.field[0]] || originParams[o.field[1]])"
									:onlyDept="o?.onlyDept || false"
									@change="search()" />
							</template>
							<template v-else-if="o.component === 'areaSelect'">
								<area-select
									v-model:city-id="params[o.field[0]]"
									v-model:area-id="params[o.field[1]]"
									v-model:town-id="params[o.field[2]]"
									@change="search()" />
							</template>
							<template v-else-if="o.component === 'dateRange'">
								<a-range-picker
									:disabled-date="o.disabledDate"
									:value="[params[o.field[0]], params[o.field[1]]]"
									:disabled="[originParams[o.field[0]], originParams[o.field[1]]]"
									allow-clear
									:value-format="DATE_FORMAT.DATE"
									:allow-empty="[true, true]"
									@calendarChange="e => onDateRangeChange(e, o)" />
							</template>
							<template v-else-if="o.component === 'numberRange'">
								<a-input-group compact class="range-input-group">
									<a-input-number
										v-model:value="params[o.field[0]]"
										:max="params[o.field[1]]"
										allow-clear
										placeholder="请输入">
										<template v-if="o.suffix" #suffix>
											{{ o.suffix }}
										</template>
									</a-input-number>
									<a-input placeholder="→" readonly class="range-input-split" />
									<a-input-number
										v-model:value="params[o.field[1]]"
										:min="params[o.field[0]]"
										allow-clear
										placeholder="请输入">
										<template v-if="o.suffix" #suffix>
											{{ o.suffix }}
										</template>
									</a-input-number>
								</a-input-group>
							</template>
							<template v-else-if="o.component === 'tag'">
								<a-radio-group v-model:value="params[o.field]" size="small" @change="search()">
									<a-space class="padding-none display-flex">
										<a-radio-button :value="null">
											<small>全部</small>
										</a-radio-button>
										<a-radio-button v-for="item in o.list" :key="item.id || item.value" :value="item.id || item.value">
											<small>{{ item.name || item.label }}</small>
										</a-radio-button>
									</a-space>
								</a-radio-group>
							</template>
							<template v-else-if="o.component === 'select'">
								<a-select v-model:value="params[o.field]" v-bind="o.option" @change="search()" />
							</template>
						</a-form-item>
					</a-form>
					<a-divider class="margin-none" />
					<vxe-toolbar @click.stop>
						<template #buttons>
							<a @click="clear">
								<svg-icon icon-class="trash" />
								清空搜索条件
							</a>
						</template>
						<template #tools>
							<a-button type="primary" @click="search(true)">
								<search-outlined />
								搜索
							</a-button>
						</template>
					</vxe-toolbar>
				</template>
			</template>
		</a-select>
	</a-input-group>
</template>

<script lang="ts" setup>
	import {onMounted, onUnmounted, reactive, ref, toRef} from 'vue'
	import {SearchOutlined} from '@ant-design/icons-vue'
	import XEUtils from 'xe-utils'
	import DeptEmpSelect from './dept-emp-select.vue'
	import AreaSelect from './area-select.vue'
	import settingApi from 'yuxin-base/src/api/setting-api'
	import {MatchType, SearchOption} from 'yuxin-base/src/types'
	import DATE_FORMAT from 'yuxin-base/src/utils/date'
	import {DEFAULT_FIELD_NAME} from 'yuxin-base/src/constant'

	const props = defineProps<{
		// 搜索参数
		params: any
		// 搜索匹配类型
		matchTypes?: MatchType[]
		// 占位提示
		placeholder?: string
		// 搜索选项配置
		options?: SearchOption[]
	}>()

	const id = Date.now().toString()
	const values = ref<any[]>([])
	const params = toRef(props, 'params')
	// 克隆原始搜索参数，用于重置搜索
	const originParams = XEUtils.clone(params.value, true)

	const option = reactive<any>({
		open: false,
		// options: [],
		showSearch: true,
		allowClear: true,
		// mode: 'multiple',
		// maxTagCount: 'responsive',
		// fieldNames: defaultFieldNames,
		placeholder: toRef(props, 'placeholder', '请输入关键字搜索'),
		dropdownClassName: 'search-select-dropdown',
		onFocus() {
			option.open = true
		},
		onSearch(keyword: string) {
			if (event instanceof InputEvent) {
				params.value.like = keyword ? keyword.trim() : null
			}
		},
		onChange(value: string) {
			if (!value) {
				search(true)
			}
		}
	})

	onMounted(() => {
		if (props.options && props.options.length) {
			props.options.forEach(o => {
				if (o.type === 'dic') {
					o.fieldNames = o.fieldNames || DEFAULT_FIELD_NAME
					if (o.dicPid) {
						settingApi.getDicListByPid(o.dicPid).then(({data}) => (o.list = data))
					} else if (o.dicLabel) {
						// 82308字典修改
						settingApi.getDicListByLabel(o.dicLabel, {isUse: 1}).then(({data}) => {
							o.list = data.filter(v => !!v.metaList.length)
						})
					}
				}
				if (o.component === 'select') {
					o.option = Object.assign(
						{
							allowClear: true,
							showSearch: true,
							fieldNames: o.fieldNames,
							placeholder: `请选择${o.label}`,
							options: toRef(o, 'list', []),
							mode: o.multiple ? 'multiple' : undefined,
							optionFilterProp: (o.fieldNames || {label: 'label'}).label
						},
						o.option
					)
				}
			})
		}
	})

	const emits = defineEmits(['search'])

	/**
	 * 重置搜索条件
	 */
	const reset = () => {
		Object.assign(params.value, originParams)
	}

	/**
	 * 清空搜索
	 */
	const clear = () => {
		reset()
		search(true)
	}

	const onDateRangeChange = (dates: string[], option: SearchOption) => {
		if (dates) {
			params.value[option.field[0]] = dates[0]
			params.value[option.field[1]] = dates[1]
		} else {
			params.value[option.field[0]] = null
			params.value[option.field[1]] = null
		}

		search(false)
	}

	const search = (close = false) => {
		option.open = !close
		event && event.stopPropagation()
		emits('search', params.value)
	}

	const close = () => {
		if (option.open && event) {
			// @ts-ignore
			const path = event.path || event.composedPath() || []

			return (option.open = path.some(dom => {
				return XEUtils.includeArrays(Array.from(dom.classList || []), ['ant-picker-dropdown'])
			}))
		}
		option.open = false
	}

	// 将方法暴露至调用层
	defineExpose({
		reset,
		clear,
		close
	})

	onMounted(() => document.addEventListener('click', close))
	onUnmounted(() => document.removeEventListener('click', close))
</script>

<style lang="less">
	@import 'yuxin-base/src/style/search-input.less';
</style>
